#pragma once
#include <cmath>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#if _WIN32
#include<Windows.h>
#elif __linux__
#include <unistd.h>
#endif
//
#define AVERROR(e) (e)

static inline  bool qFuzzyCompare1(float p1, float p2)
{
	return (std::abs(p1 - p2) * 100000.f <= std::fmin(std::abs(p1), std::abs(p2)));
}


template <typename T>
 const T& Bound(const T& min, const T& val, const T& max)
{
	return std::fmax(min, std::fmin(max, val));
}


template<typename ... Args>
static std::string str_format(const std::string& format, Args ... args)
{
	auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1;
	std::unique_ptr<char[]> buf(new(std::nothrow) char[size_buf]);

	if (!buf)
		return std::string("");

	std::snprintf(buf.get(), size_buf, format.c_str(), args ...);
	return std::string(buf.get(), buf.get() + size_buf - 1);
}

template<typename ... Args>
static std::wstring wstr_format(const std::wstring& format, Args ... args)
{
	auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1;
	std::unique_ptr<char[]> buf(new(std::nothrow) char[size_buf]);

	if (!buf)
        return std::wstring(L"");

	std::snprintf(buf.get(), size_buf, format.c_str(), args ...);
	return std::wstring(buf.get(), buf.get() + size_buf - 1);
}


inline std::vector<unsigned char> HexStringToBytes(const std::string& hex) {
	std::vector<unsigned char> bytes;

	for (unsigned int i = 0; i < hex.length(); i += 2) {
		std::string byteString = hex.substr(i, 2);
		char byte = (char)strtol(byteString.c_str(), NULL, 16);
		bytes.push_back(byte);
	}

	return bytes;
}



inline std::string Bytes2HexString(const unsigned char* str, int n)
{
	std::ostringstream oss;
	oss << std::hex;
	oss << std::setfill('0');
	oss << std::uppercase;   //大写
	for (int i = 0; i < n; i++)
	{
		unsigned char c = str[i];
		oss <<  std::setw(2) << (unsigned int)c;

	}
	return oss.str();
}

//返回毫秒
inline time_t av_time(void)
{
#ifdef WIN32
	return GetTickCount64();
#elif _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK)
	struct timespec tp;
	clock_gettime(CLOCK_MONOTONIC, &tp); 
	return tp.tv_nsec/ 1000000;
#elif defined(__APPLE__)
	static mach_timebase_info_data_t tb;
	uint64_t ticks;
	uint64_t sec;
	ticks = mach_absolute_time();
	if (tb.denom == 0) {
		mach_timebase_info(&tb);
	}
	sec = ticks * tb.numer / tb.denom / 1000000;
	return (time_t)sec;
#else
	return time(NULL);
#endif
}
